1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package storm.starter.tools;
19
20 import org.testng.annotations.DataProvider;
21 import org.testng.annotations.Test;
22
23 import java.util.Map;
24
25 import static org.fest.assertions.api.Assertions.assertThat;
26
27 public class SlidingWindowCounterTest {
28
29 private static final int ANY_WINDOW_LENGTH_IN_SLOTS = 2;
30 private static final Object ANY_OBJECT = "ANY_OBJECT";
31
32 @DataProvider
33 public Object[][] illegalWindowLengths() {
34 return new Object[][]{ { -10 }, { -3 }, { -2 }, { -1 }, { 0 }, { 1 } };
35 }
36
37 @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "illegalWindowLengths")
38 public void lessThanTwoSlotsShouldThrowIAE(int windowLengthInSlots) {
39 new SlidingWindowCounter<Object>(windowLengthInSlots);
40 }
41
42 @DataProvider
43 public Object[][] legalWindowLengths() {
44 return new Object[][]{ { 2 }, { 3 }, { 20 } };
45 }
46
47 @Test(dataProvider = "legalWindowLengths")
48 public void twoOrMoreSlotsShouldBeValid(int windowLengthInSlots) {
49 new SlidingWindowCounter<Object>(windowLengthInSlots);
50 }
51
52 @Test
53 public void newInstanceShouldHaveEmptyCounts() {
54
55 SlidingWindowCounter<Object> counter = new SlidingWindowCounter<Object>(ANY_WINDOW_LENGTH_IN_SLOTS);
56
57
58 Map<Object, Long> counts = counter.getCountsThenAdvanceWindow();
59
60
61 assertThat(counts).isEmpty();
62 }
63
64 @DataProvider
65 public Object[][] simulatedCounterIterations() {
66 return new Object[][]{ { 2, new int[]{ 3, 2, 0, 0, 1, 0, 0, 0 }, new long[]{ 3, 5, 2, 0, 1, 1, 0, 0 } },
67 { 3, new int[]{ 3, 2, 0, 0, 1, 0, 0, 0 }, new long[]{ 3, 5, 5, 2, 1, 1, 1, 0 } },
68 { 4, new int[]{ 3, 2, 0, 0, 1, 0, 0, 0 }, new long[]{ 3, 5, 5, 5, 3, 1, 1, 1 } },
69 { 5, new int[]{ 3, 2, 0, 0, 1, 0, 0, 0 }, new long[]{ 3, 5, 5, 5, 6, 3, 1, 1 } },
70 { 5, new int[]{ 3, 11, 5, 13, 7, 17, 0, 3, 50, 600, 7000 },
71 new long[]{ 3, 14, 19, 32, 39, 53, 42, 40, 77, 670, 7653 } }, };
72 }
73
74 @Test(dataProvider = "simulatedCounterIterations")
75 public void testCounterWithSimulatedRuns(int windowLengthInSlots, int[] incrementsPerIteration,
76 long[] expCountsPerIteration) {
77
78 SlidingWindowCounter<Object> counter = new SlidingWindowCounter<Object>(windowLengthInSlots);
79 int numIterations = incrementsPerIteration.length;
80
81 for (int i = 0; i < numIterations; i++) {
82 int numIncrements = incrementsPerIteration[i];
83 long expCounts = expCountsPerIteration[i];
84
85
86 boolean expAbsent = ((expCounts == 0) && ((i == 0) || (expCountsPerIteration[i - 1] == 0)));
87
88
89 for (int j = 0; j < numIncrements; j++) {
90 counter.incrementCount(ANY_OBJECT);
91 }
92
93
94 Map<Object, Long> counts = counter.getCountsThenAdvanceWindow();
95
96
97 if (expAbsent) {
98 assertThat(counts).doesNotContainKey(ANY_OBJECT);
99 }
100 else {
101 assertThat(counts.get(ANY_OBJECT)).isEqualTo(expCounts);
102 }
103 }
104 }
105
106 }